package jp.seraph.jsade.sexpression;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

/**
 * Nodeのデフォルト実装
 */
public class DefaultNode implements Node {

    public DefaultNode(List<SExpression> aBaseNode){
        mNodes = aBaseNode;
    }

    public DefaultNode(SExpression... aBaseNode){
        this(Arrays.asList(aBaseNode));
    }

    public DefaultNode(){
        this(new ArrayList<SExpression>());
    }

    private List<SExpression> mNodes;

    
    public void addChild(SExpression aExpression){
        mNodes.add(aExpression);
    }

    
    public void addChild(String aValue){
        mNodes.add(new DefaultLeaf(aValue));
    }
    
    public void insertChild(SExpression value, int index) {
        mNodes.add(index, value);
    }

    public void insertChild(String value, int index) {
        this.insertChild(new DefaultLeaf(value), index);
    }

    public void accept(ExpressionVisitor aVisitor) {
        aVisitor.visit(this);
    }

    
    public int childCount() {
        return mNodes.size();
    }

    
    public SExpression getChild(int aIndex) {
        if(0 <= aIndex && aIndex < mNodes.size()){
            return mNodes.get(aIndex);
        }else{
            return null;
        }
    }

    
    public Leaf getChildAsLeaf(int aIndex) {
        SExpression tChild = getChild(aIndex);
        if(tChild == null) return null;

        if(tChild.isLeaf())
            return (Leaf)tChild;
        else
            return null;
    }

    
    public Node getChildAsNode(int aIndex) {
        SExpression tChild = getChild(aIndex);
        if(tChild == null) return null;

        if(tChild.isNode())
            return (Node)tChild;
        else
            return null;
    }

    
    public String getLeftString() {
        if(this.childCount() == 0) return null;
        return getChild(0).getLeftString();
    }

    
    public boolean isLeaf() {
        return false;
    }

    
    public boolean isNode() {
        return true;
    }
    
    public String getValue(String aName) {
        for(SExpression tExpression : mNodes){
            if(tExpression.childCount() == 2){
                if(tExpression.getChild(0).isLeaf() && tExpression.getChild(1).isLeaf()){
                    if(aName.equals(tExpression.getChildAsLeaf(0).getValue()))
                        return tExpression.getChildAsLeaf(1).getValue();
                }
            }
        }

        return null;
    }
    

    /**
     *
     * @see jp.seraph.jsade.sexpression.Node#getValues(java.lang.String)
     */
    public String[] getValues(String aName) {
        for(SExpression tExpression : mNodes){
            if(tExpression.childCount() >= 2){
                if(((Node)tExpression).allChildIsLeaf()){
                    if(aName.equals(tExpression.getChildAsLeaf(0).getValue())){
                        String[] tResult = new String[tExpression.childCount() - 1];
                        for(int i=0; i< tExpression.childCount() - 1; i++){
                            tResult[i] = tExpression.getChildAsLeaf(i + 1).getValue();
                        }
                        
                        return tResult;
                    }
                }
            }
        }
        
        return new String[0];
    }
    
    public boolean allChildIsLeaf(){
        for(SExpression tExpr : this){
            if(tExpr.isNode())
                return false;
        }
        
        return true;
    }

    /**
     *
     * @see java.lang.Iterable#iterator()
     */
    public Iterator<SExpression> iterator() {
        return mNodes.iterator();
    }
}
